Unreal Shader学习
安装及基础概念
知乎 《Shader从入门到放弃》 在VS中可以安装ShaderToy来观测GLSL
👆这个文字教程也是很不错的
Unreal 5.0 材质中添加自定义 Shader 代码 在UE中需要设置Shder文件的位置
<img src=”https://s2.loli.net/2025/09/13/CxzRNf1Witu69IU.png“ alt=”Unreal Sha原本的3D流程应该是:”原画师绘制场景图(将3D场景画下来) -> 建模师根据原画构建场景模型(产出3D模型)-> 程序渲染(将3D模型导入到引擎中,或者其他3D渲染库),然后渲染成画面”。
主要是两种着色器:
Fragment Shader(片元shader):输入插值后的顶点数据,输出最终像素颜色(
fragColor)。Vertex Shader(顶点Shader):输入单个顶点数据(位置/法线等),输出处理后的顶点位置(
gl_Position)和其他插值数据。compute shader 计算着色器
geometry shader 几何着色器
….
HLSL
基础的语法
| min max |
最大最小 |
|---|---|
| abs |
绝对值 |
| fmod |
取余操作 |
| round |
四舍五入 |
| pow |
指数 |
| sqrt rsqrt |
平方根 和 倒数平方根 |
| degrees(x) redians |
弧度转角度 角度转弧度 |
| length |
向量到原点的距离 |
| frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); |
噪声算法 |
| sin cos tan |
三角函数 |
| asin acos atan |
他们的反函数 |
| sinh cosh tanh |
双曲线函数 |
| ceil |
数值范围函数 |
UV坐标系说明:
- 原点 (0,0) 位于左下角
- (0,1) 左上角,(1,1) 右上角,(1,0) 右下角
GLSL
基础语法
step
如果x 小于某个值,则返回 0,如果大于等于这个值,则返回1。
所以上面的代码可以简化成:
1 | // if(abs(uv.x) <= 2. * fwidth(uv.x)) { |
mix
该函数的实际上执行的就是一个简单的 线性差值。 简单的说就是:当a = 1时,返回的值为y, 但a = 0时,返回x的值,如果返回的值为0.5,则返回
0.5x + 0.5y的值,同理,如果a = 0.2, 返回0.8 * a + 0.2 * y。
我们可以利用这个函数来做颜色叠加,颜色叠加的公式可以写为:
$$
Color=Src.color∗(1−Dst.a)+Dst.color∗Dst.a
$$
smoothstep
我们可以直观的看出:当x < 0时,返回0,当 x > 1时,返回1,如果 x 处于0~1之间时,则有一个类似于线性插值的过渡,但是请注意,这里并不是线性插值,因为在接近两端的值的时候,该函数有一个平滑的过渡。所以我们可以通过这一点来对 step 函数进行替换以解决锯齿的问题。
floor
作用是向下取整,它会返回不大于输入值的最大整数。例如:对 uv 向量的每个分量(x和y)分别执行向下取整
例如:
1 | floor(3.7)` → `3.0 |
核心步骤(渲染管线)
- 顶点变换的过程(顶点着色器)
- 图元装配(按哪种方式装配图元,装配为点,线还是三角形)
- 光栅化(将上述的图元从矢量图形转换为像素组成的图形)
- 着色(片段着色器)
- 测试(Alpha测试,深度测试,模板测试等)& 混合
坐标系
这是左手坐标系 反之是右手坐标系
OpenGL是右手坐标系
实现代码
1. 最初始的实例代码 (实现一个坐标轴):
1 | // 归一化uv坐标到[-1,1]范围,保持宽高比 |
https://www.shadertoy.com/view/Wf2fRw
这个shader创建了一个坐标系统,包含网格线和彩色坐标轴。
2. 实现函数的y=kx的绘制
1 | // 归一化uv坐标到[-1,1]范围,保持宽高比 |
https://www.shadertoy.com/view/3c2fzw
3. 实现一段复杂函数的绘制(分段绘制)
1 |
|
https://www.shadertoy.com/view/Wc2fzw
4. 实现一个(静态)星芒效果
1 |
|
5. 随机数生成办法
1 | vec2 N22(vec2 p) { |
6. 星星连线效果
1 |
|
7. 星星推进(博主的版本)
1 | vec2 N22(vec2 p) { |
8.一个最简单的3D点
原本的3D流程应该是:“原画师绘制场景图(将3D场景画下来) -> 建模师根据原画构建场景模型(产出3D模型)-> 程序渲染(将3D模型导入到引擎中,或者其他3D渲染库),然后渲染成画面”。
我们简要回顾一下:
- 顶点变换的过程(顶点着色器)
- 图元装配(按哪种方式装配图元,装配为点,线还是三角形)
- 光栅化(将上述的图元从矢量图形转换为像素组成的图形)
- 着色(片段着色器)
- 测试(Alpha测试,深度测试,模板测试等)& 混合
通过上述方式渲染的3D模型的方式我们通常称为光栅化的方法
而在我们的shadertoy中,我们是直接在片段着色器中进行编程,我们只有上述的第四与第五步的过程。其实相当于我们现在变成了原画师,我们需要在一张纸上做画,而且画的是3D场景。好在我们还有另一种构建3D场景的方式,就是光线追踪或光线步进。
https://juejin.cn/post/7362059823662432306
1 | // 点p到直线ro到rd的距离 |
100.一个海Shader(优化版本)
1 | /* |
ShaderToy
常用的全局变量
* ⚠️警告
- 尽可能不要在Shader中写 If 逻辑代码,因为不能充分发挥SIMD的性能
* 其他专有名词解释
- 齐次坐标:用 n + 1 维向量来表示 n 维向量。比如在 2D 中,点 (x, y) 用 (x, y, w) 表示,w 通常为 1,若 w = 0 则表示无穷远点;在 3D 里,点 (x, y, z) 表示为 (x, y, z, w) 。它能简化图形学计算,还可表示无穷远点 。